/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.admin.entity;

import vip.dexian.core.base.bean.BaseEntity;
import vip.dexian.core.base.bean.TreeEntity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Where;
import org.hibernate.validator.constraints.Length;

import java.io.Serial;
import java.util.Set;

/**
 * 部门
 *
 * @author 挺好的 2023年05月31日 9:09
 */

@Entity
@Table (name = "br_admin_department", indexes = {@Index (name = "is_valid", columnList = "isValid")})
@DynamicUpdate
@Where (clause = BaseEntity.IS_VALID_WHERE)
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode (callSuper = true)
public class Department extends TreeEntity <Long> {

    @Serial
    private static final long serialVersionUID = 3112958017740842178L;

    /**
     * 部门名称
     */
    @NotBlank (message = "部门名称不能为空")
    @Length (min = 2, max = 20, message = "部门名称的长度应在{min}和{max}个字符之间")
    @Comment ("部门名称")
    @Column (nullable = false, length = 20)
    private String name;

    /**
     * 是否启用
     */
    @NotNull (message = "是否启用不能为空")
    @Comment ("是否启用")
    @Column (nullable = false)
    private Boolean isEnabled;

    /**
     * 上级部门（自关联）
     */
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @JsonIgnore
    @Comment ("上级部门")
    @ManyToOne (targetEntity = Department.class, fetch = FetchType.LAZY)
    @JoinColumn (name = "parent_id",
            foreignKey = @ForeignKey (name = "parent_id", value = ConstraintMode.NO_CONSTRAINT))
    private Department parent;

    /**
     * 自关联
     */
    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @JsonIgnore
    @OneToMany (mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private Set <Department> children;

}
